/*******************************************************************************
 * Copyright (c) 2000, 2007 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package ch.uzh.ifi.sonar.shells;

/**
 * Launch the browser to show different birt reports. Tab class and this browser class need to be refactored.
 * */

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.birt.report.viewer.utilities.WebViewer;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTError;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.browser.OpenWindowListener;
import org.eclipse.swt.browser.WindowEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Widget;
import org.osgi.framework.Bundle;

import ch.uzh.ifi.sonar.util.SonarUtility;

class BrowserTab extends Tab {

	/* Example widgets and groups that contain them */
	Browser browser;
	Group browserGroup;

	/* Style widgets added to the "Style" group */
	Button mozillaButton, webKitButton;

	String errorMessage, lastText, lastUrl;

	private String reportPath;
	private String tabTitle;

	private static final String[] strings = { "PROJECT_MANAGER_STR",
			"GENERAL_MANAGER_STR", "DEVELOPER_STR", "TESTER_STR", "MODULE_COMPLEXITY_STR" };

	private final Map<String, String> reportMaps;

	/* control widgets and groups that control the example main group widgets */
	private Combo reportCombo;
	private Button reportAdditionCheckBox;
	
	private Text eventConsole;
	
	/* log group */
	private Group consoleGroup;

	/**
	 * Creates the Tab within a given instance of ControlExample.
	 */
	BrowserTab(SonarDashboard instance) {
		super(instance);
		this.reportPath = "";
		this.tabTitle = "Dashboard";
		reportMaps = new HashMap<String, String>();
		String reportKey = null;
		for (String key : strings) {
			reportKey = key.substring(0, key.lastIndexOf("STR")) + "REPORT";
			reportMaps.put(SonarUtility.getResourceString(key),
					SonarUtility.getResourceString(reportKey));
		}

	}

	/*
	 * BrowserTab(SonarDashboard instance, String reportPath, String tabTitle) {
	 * super(instance); this.reportPath = reportPath; this.tabTitle = tabTitle;
	 * }
	 */
	
	@Override
	protected void fillContent(){
		super.fillContent();
		//createConsoleGroup();
		refreshBrowserGroup();
	}

	@Override
	protected void createControlGroup() {
		controlGroup = new Group(tabFolderPage, SWT.NONE);
		controlGroup.setLayout(new GridLayout(2, true));
		controlGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false,
				false));
		controlGroup.setText("Report Type");

	}

	private String selectedReportPath;
	private String reportViewerOptions;

	void createControlWidgets() {

		reportCombo = new Combo(controlGroup, SWT.READ_ONLY);
		reportCombo.setItems((String[]) reportMaps.keySet().toArray(
				new String[reportMaps.size()]));
		reportCombo.setText(reportCombo.getItem(0));
		reportCombo.setVisibleItemCount(strings.length);
		reportCombo.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				setSelectedReportPath(reportMaps.get(reportCombo.getText()));
				refreshBrowserGroup();
			}

		});

		reportAdditionCheckBox = new Button(controlGroup, SWT.CHECK);
		reportAdditionCheckBox.setText("Open with additional functions");
		reportAdditionCheckBox
				.setToolTipText("for retrieving Table of Contents, exporting to CSV, parameter entry and paging controls.");
		reportAdditionCheckBox.setSelection(true);
		flipReportViewOptions();
		reportAdditionCheckBox.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				
				flipReportViewOptions();
				refreshBrowserGroup();
			}
		});			
	}	
	void flipReportViewOptions(){
		if (reportAdditionCheckBox.getSelection())
			setReportViewerOptions("frameset");
		else
			setReportViewerOptions("run");
	}

	void createBackgroundModeGroup() {
		// Browser does not need a background mode group.
	}

	void createColorAndFontGroup() {
		// Browser does not need a color and font group.
	}

	/**
	 * Creates the "Example" group.
	 */
	void createMainGroup() {
		super.createMainGroup();
		/* Create a group for the browser */
		browserGroup = new Group(exampleGroup, SWT.NONE);
		browserGroup.setLayout(new GridLayout());
		browserGroup
				.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		//browserGroup.setText("");
	}

	/**
	 * Creates the "Example" widgets.
	 */
	void createExampleWidgets() {
		//createBrowser("DEFAULT_REPORT", "run"); // set the browser
	}

	@SuppressWarnings("deprecation")
	private void createBrowser(String reportPathStr, String option) {
		/* Compute the widget style */
		int style = getDefaultStyle();
		/* Create the example widgets */
		try {
			browser = new Browser(browserGroup, SWT.NONE);
			GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
			gridData.grabExcessHorizontalSpace = true;
			gridData.grabExcessVerticalSpace = true;
			browser.setLayoutData(gridData);	
			WebViewer.startup(browser);
			WebViewer.display(this.getReportAbosolutePath(reportPathStr), WebViewer.HTML, browser, option);
			/* this is to fix the error that printing and exporting function has errors, when frameset options was selected, */
			browser.addOpenWindowListener(new OpenWindowListener() {
				public void open(final WindowEvent event) {
					final Shell shell = new Shell(SWT.SHELL_TRIM);
					shell.setLayout(new FillLayout());
					Browser browser = new Browser(shell, SWT.NONE);
					event.browser = browser;
					shell.open();
				}
			});
			

			// browser.setText("<HTML><BODY><H1>" + this.getReportAbosolutePath(reportPathStr) +  "</H1></BODY></HTML>");
		} catch (SWTError e) { // Probably missing browser
			try {
				browser = new Browser(browserGroup, style
						& ~(SWT.MOZILLA | SWT.WEBKIT));
			} catch (SWTError e2) { // Unsupported platform
				errorMessage = e.getMessage();
				return;
			}
		} catch (MalformedURLException me) {
			System.out.println("Failed in URL " + me.getStackTrace());
		} catch (IOException e) {
			errorMessage = e.getMessage();
			return;
		} 
	}
	
	private String getReportAbosolutePath(String relativePathStr) throws IOException{
		String viewerReportPath = SonarUtility
				.getResourceString(relativePathStr);
		if (reportCombo != null) {
			viewerReportPath = reportMaps.get(reportCombo.getText());
		}
		Bundle bundle = Platform.getBundle("ch.uzh.ifi.sonar");
		
		URL url = FileLocator
				.find(bundle, new Path(viewerReportPath), null);
		return FileLocator.toFileURL(url).getPath();
		
	}

	private void refreshBrowserGroup() {
		if(browserGroup !=null){
			Control[] browsers = browserGroup.getChildren();
			for (Control control : browsers) {
				control.dispose();
			}
			createBrowser(this.getSelectedReportPath(),
					this.getReportViewerOptions());
			browserGroup.layout(true, true);
		}
	
		
	}

	/**
	 * Creates the tab folder page.
	 * 
	 * @param tabFolder
	 *            org.eclipse.swt.widgets.TabFolder
	 * @return the new page for the tab folder
	 */
	Composite createTabFolderPage(final TabFolder tabFolder) {
		super.createTabFolderPage(tabFolder);
		return tabFolderPage;
	}

	/**
	 * Disposes the "Example" widgets.
	 */
	void disposeExampleWidgets() {
		/* store the state of the Browser if applicable */
		if (browser != null) {
			String url = browser.getUrl();
			if (url.length() > 0 && !url.equals("about:blank")) { //$NON-NLS-1$
				lastUrl = url;
			} else {
				String text = browser.getText();
				if (text.length() > 0) {
					lastText = text;
				}
			}
		}
		super.disposeExampleWidgets();
	}

	public static String getContents(InputStream in) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(in));

		StringBuffer sb = new StringBuffer(300);
		try {
			int read = 0;
			while ((read = br.read()) != -1)
				sb.append((char) read);
		} finally {
			br.close();
		}
		return sb.toString();
	}

	/**
	 * Gets the list of custom event names.
	 * 
	 * @return an array containing custom event names
	 */
	String[] getCustomEventNames() {
		return new String[] { "CloseWindowListener", "LocationListener",
				"OpenWindowListener", "ProgressListener", "StatusTextListener",
				"TitleListener", "VisibilityWindowListener" };
	}

	/**
	 * Gets the "Example" widget children.
	 */
	@Override
	Widget[] getExampleWidgets() {
		if (browser != null)
			return new Widget[] { browser };
		return null;

	}

	/**
	 * Returns a list of set/get API method names (without the set/get prefix)
	 * that can be used to set/get values in the example control(s).
	 */
	String[] getMethodNames() {
		return new String[] { "Text", "Url", "ToolTipText" };
	}

	/**
	 * Gets the text for the tab folder item.
	 */
	String getTabText() {
		return this.tabTitle == null ? "Dashboard" : this.tabTitle;
	}

	/**
	 * Sets the state of the "Example" widgets.
	 */
	void setExampleWidgetState() {
		super.setExampleWidgetState();
		mozillaButton.setSelection(browser == null ? false : (browser
				.getStyle() & SWT.MOZILLA) != 0);
		webKitButton.setSelection(browser == null ? false
				: (browser.getStyle() & SWT.WEBKIT) != 0);

	}

	public String getSelectedReportPath() {
		if (selectedReportPath == null)
			return SonarUtility.getResourceString("DEFAULT_REPORT");
		else
			return selectedReportPath;
	}

	public void setSelectedReportPath(String selectedReportPath) {
		this.selectedReportPath = selectedReportPath;
	}

	public String getReportViewerOptions() {
		if (reportViewerOptions == null)
			return "run";
		else
			return reportViewerOptions;
	}

	public void setReportViewerOptions(String reportViewerOptions) {
		this.reportViewerOptions = reportViewerOptions;
	}
	
	private void createConsoleGroup(){
		consoleGroup = new Group(tabFolderPage, SWT.NONE);
		consoleGroup.setLayout(new GridLayout(3, false));
		consoleGroup
				.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		consoleGroup.setText("Log Panel");
		
		
		/*
		 * Create the button to clear the text.
		 */
		Button clearButton = new Button(consoleGroup, SWT.PUSH);
		clearButton.setText("Clear");
		clearButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
		clearButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				eventConsole.setText("");
			}
		});
		eventConsole = new Text(consoleGroup, SWT.BORDER | SWT.MULTI
				| SWT.V_SCROLL | SWT.H_SCROLL);
		GridData gd = new GridData(GridData.FILL_BOTH);
		gd.horizontalSpan = 3;
		gd.heightHint = 80;
		eventConsole.setLayoutData(gd);

	}
	
	/**
	 * Logs a string to the event console.
	 */
	void log(String string) {
		if (!eventConsole.isDisposed()) {
			eventConsole.append(string);
			eventConsole.append("\n");
		}
	}
}
